@file:JvmMultifileClass
@file:JvmName("CalendarUtils")

package hos.kotlin

import java.text.SimpleDateFormat
import java.util.Calendar

/**
 * <p>Title: CalendarExt </p>
 * <p>Description:  </p>
 * <p>Company: www.mapuni.com </p>
 *
 * @author : 蔡俊峰
 * @date : 2024-07-17 17:26
 * @version : 1.0
 */
@Suppress("SimpleDateFormat")
fun Calendar.string(pattern: String = TimeFormat.full): String {
    return SimpleDateFormat(pattern).format(time)
}

fun Calendar.year(): Int {
    return get(Calendar.YEAR)
}

fun Calendar.month(): Int {
    return get(Calendar.MONTH) + 1
}

fun Calendar.monthSize(): Int {
    val actualMinimum = getActualMaximum(Calendar.DAY_OF_MONTH)
    set(Calendar.DAY_OF_MONTH, actualMinimum)
    return get(Calendar.DAY_OF_MONTH)
}

fun Calendar.day(): Int {
    return get(Calendar.DAY_OF_MONTH)
}

fun Calendar.startYear(): Calendar {
    //设置月份,由于月份下标从0开始 所以赋值月份要-1
    set(Calendar.MONTH, 0)
    //设置日期
    set(Calendar.DAY_OF_MONTH, 1)
    return startDay()
}

fun Calendar.endYear(): Calendar {
    //设置月份,由于月份下标从0开始 所以赋值月份要-1
    set(Calendar.MONTH, 11)
    //设置日期
    set(Calendar.DAY_OF_MONTH, 31)
    return endDay()
}

fun Calendar.startMonth(): Calendar {
    val actualMinimum = getActualMinimum(Calendar.DAY_OF_MONTH)
    set(Calendar.DAY_OF_MONTH, actualMinimum)
    return startDay()
}

fun Calendar.endMonth(): Calendar {
    val actualMinimum = getActualMaximum(Calendar.DAY_OF_MONTH)
    set(Calendar.DAY_OF_MONTH, actualMinimum)
    return endDay()
}

fun Calendar.startWeek(): Calendar {
    timeInMillis
    val actualMinimum = firstDayOfWeek
    set(Calendar.DAY_OF_WEEK, actualMinimum)
    return startDay()
}

fun Calendar.endWeek(): Calendar {
    timeInMillis
    val actualMinimum = firstDayOfWeek
    set(Calendar.DAY_OF_WEEK, actualMinimum)
    add(Calendar.DAY_OF_WEEK, 6)
    return endDay()
}

fun Calendar.startDay(): Calendar {
    //设置小时
    set(Calendar.HOUR_OF_DAY, 0)
    //设置分钟
    set(Calendar.MINUTE, 0)
    //设置秒
    set(Calendar.SECOND, 0)
    return this
}

fun Calendar.endDay(): Calendar {
    //设置小时
    set(Calendar.HOUR_OF_DAY, 23)
    //设置分钟
    set(Calendar.MINUTE, 59)
    //设置秒
    set(Calendar.SECOND, 59)
    return this
}

fun Calendar.yesterday(): Calendar {
    add(Calendar.DAY_OF_MONTH, -1)
    return this
}

fun Calendar.yesterdayBefore(): Calendar {
    add(Calendar.DAY_OF_MONTH, -2)
    return this
}

fun Calendar.tomorrow(): Calendar {
    add(Calendar.DAY_OF_MONTH, 1)
    return this
}

fun Calendar.tomorrowAfter(): Calendar {
    add(Calendar.DAY_OF_MONTH, 2)
    return this
}


fun Calendar.subtractYear(time: Int): Calendar {
    add(Calendar.YEAR, -time)
    return this
}

fun Calendar.subtractMonth(time: Int): Calendar {
    add(Calendar.MONTH, -time)
    return this
}

fun Calendar.subtractDay(time: Int): Calendar {
    add(Calendar.DAY_OF_MONTH, -time)
    return this
}

fun Calendar.subtractHour(time: Int): Calendar {
    add(Calendar.HOUR, -time)
    return this
}

fun Calendar.subtractMinute(time: Int): Calendar {
    add(Calendar.MINUTE, -time)
    return this
}

fun Calendar.subtractSecond(time: Int): Calendar {
    add(Calendar.SECOND, -time)
    return this
}

fun Calendar.subtract30(): Calendar {
    add(Calendar.DAY_OF_MONTH, -30)
    return this
}

fun Calendar.subtract7(): Calendar {
    add(Calendar.DAY_OF_MONTH, -7)
    return this
}

fun Calendar.addYear(time: Int): Calendar {
    add(Calendar.YEAR, time)
    return this
}

fun Calendar.addMonth(time: Int): Calendar {
    add(Calendar.MONTH, time)
    return this
}

fun Calendar.addDay(time: Int): Calendar {
    add(Calendar.DAY_OF_MONTH, time)
    return this
}

fun Calendar.addHour(time: Int): Calendar {
    add(Calendar.HOUR, time)
    return this
}

fun Calendar.addMinute(time: Int): Calendar {
    add(Calendar.MINUTE, time)
    return this
}

fun Calendar.addSecond(time: Int): Calendar {
    add(Calendar.SECOND, time)
    return this
}

fun Calendar.isSame(calendar: Calendar): Boolean {
    return this.timeInMillis == calendar.timeInMillis
}

fun Calendar.isSame(calendar: Long): Boolean {
    return this.timeInMillis == calendar
}

fun Calendar.isBefore(end: Calendar): Boolean {
    return this.timeInMillis < end.timeInMillis
}

fun Calendar.isAfter(start: Calendar): Boolean {
    return this.timeInMillis > start.timeInMillis
}

fun main() {
    val calendar = Calendar.getInstance()
    println("monthSize:" + Calendar.getInstance().monthSize())
    println("startYear:"+calendar.startYear().string())
    println("endYear:"+calendar.endYear().string())
    println("startMonth:"+Calendar.getInstance().startMonth().string())
    println("endMonth:"+Calendar.getInstance().endMonth().string())
    println("startDay:"+Calendar.getInstance().startDay().string())
    println("endDay:"+Calendar.getInstance().endDay().string())
    println("startWeek:"+Calendar.getInstance().startWeek().string())
    println("endWeek:"+Calendar.getInstance().endWeek().string())
    println("yesterday:"+Calendar.getInstance().yesterday().string())
    println("yesterdayBefore:"+Calendar.getInstance().yesterdayBefore().string())
    println("tomorrow:"+Calendar.getInstance().tomorrow().string())
    println("tomorrowAfter:"+Calendar.getInstance().tomorrowAfter().string())
    println("startMonth startWeek:"+Calendar.getInstance().startMonth().startWeek().string())
    println("startMonth endWeek:"+Calendar.getInstance().startMonth().endWeek().string())
    println("endMonth endWeek:"+Calendar.getInstance().endMonth().startWeek().string())
    println("endMonth endWeek:"+Calendar.getInstance().endMonth().endWeek().string())
    println("y_mo_d:"+"2024-07-20".calendar(TimeFormat.y_mo_d).string())
}